import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;

import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ProgressMonitor;
import javax.swing.SpringLayout;


public class mailRemover {
	public static void main(String[] args) {
		// Schedule a job for the event-dispatching thread:
		// creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				mailRemoverGUI mrGUI = new mailRemoverGUI();
			}
		});
	}
}

class mailRemoverGUI extends JFrame {
	private final String VERSION = "0.7";
	private int delMail = 0;
	private Message [] messages;
	private Folder inbox;
	private Store store;
	private boolean isInputted = false;

	// GUI Components
	private mailRemoverGUI mrGUI;
	private JPanel northPanel;
	private JLabel hostLabel, usernameLabel, passwordLabel;
	private JTextField hostTextField, userTextField;
	private JPasswordField userPasswordField;
	private JButton connectButton;
	private JTextArea clientTextArea;
	private JScrollPane scrollArea;
	private ProgressMonitor m_progress;

	private class connectPressed implements ActionListener {
		public void actionPerformed(ActionEvent ae) {
			// If user had input user name and password then do login.
			if((hostTextField.getText().length() > 0) &&
					(userTextField.getText().length() > 0)) {
				// Flush text area.
				clientTextArea.setText("");
				
				// Disable connect button.
				connectButton.setEnabled(false);

				// set cursor to busy state.
				mrGUI.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

				// Set up the properties for the mail session
				Properties props = new Properties();
				props.put("mail.host", hostTextField.getText());

				try {
					// Get store
					Session mrSession = Session.getInstance(props, null);
					store = mrSession.getStore("pop3");
					store.connect(hostTextField.getText(), userTextField.getText(), userPasswordField.getText());

					// Get folder
					inbox = store.getFolder("INBOX");
					inbox.open(Folder.READ_WRITE);

					// Get directory
					messages = inbox.getMessages();

				}

				catch (MessagingException e) {
					// Print error message.
					clientTextArea.append(e.getMessage());
					
					// Set cursor to normal state.
					mrGUI.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
					
					// Enable connect button
					connectButton.setEnabled(true);
					return;
				}

				// Set cursor to normal state.
				mrGUI.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

				// If Mailbox is empty then do nothing.
				if(messages.length == 0) {
					JOptionPane.showMessageDialog(null, "The mailbox is empty!", "Information", JOptionPane.INFORMATION_MESSAGE);
					// Close connection
					try {
						inbox.close(false);
						store.close();
					}
					catch(MessagingException e) {
						clientTextArea.append(e.getMessage());
					}

					// Enable connect button.
					connectButton.setEnabled(true);
					return;
				}

				// Retrieve user input
				do {
					String inputValue = JOptionPane.showInputDialog(
							"There are " + messages.length + " mail(s) on server, how many you would like to delete?", messages.length);

					// If user press cancel button then do nothing.
					if(inputValue == null) {
						try {
							inbox.close(false);
							store.close();
						}
						
						catch(MessagingException e) {
							clientTextArea.append(e.getMessage());
						}
						
						// Enable connect button.
						connectButton.setEnabled(true);
						
						return;
						
						// Data validate
					} else if(inputValue.length() > 0) {
						try {
							delMail = Integer.parseInt(inputValue);
						}
						catch(NumberFormatException ex) {
							JOptionPane.showMessageDialog(
									null, "The specified number is out of range.", "Warning", JOptionPane.WARNING_MESSAGE);
							continue;
						}
					}
					if((delMail <= 0) || (delMail > messages.length)) {
						JOptionPane.showMessageDialog(
								null, "The specified number is out of range.", "Warning", JOptionPane.WARNING_MESSAGE);
						continue;
					}
					isInputted = true;
				} while(isInputted == false);

				// Processing indicator
				m_progress = new ProgressMonitor(mrGUI, "Processing","", 0, 100);
				m_progress.setMinimum(0);
				m_progress.setMaximum(delMail - 1);
				Thread runner = new Thread(new Runnable() {
					public void run() {

						for(int i = 0; i < delMail && !m_progress.isCanceled(); i++) {
							try {
								messages[i].setFlag(Flags.Flag.DELETED, true);
							}
							catch(MessagingException e) {
								clientTextArea.append(e.getMessage());
							}
							m_progress.setProgress(i);
							try {
								Thread.sleep(1);
							}
							catch(InterruptedException ignore) {}

							// Task canceled
							if(m_progress.isCanceled()) {
								try {
									inbox.close(false);
									store.close();
								}
								catch(MessagingException e) {
									clientTextArea.append(e.getMessage());
								}

								clientTextArea.append("Canceled\n");
								// Enable connect button.
								connectButton.setEnabled(true);
								return;
							}
						}
						try {
							inbox.close(true);
							store.close();
						}
						catch(MessagingException e) {
							clientTextArea.append(e.getMessage());
						}
						clientTextArea.append("[Info: ]The mail deletion is done, server might need few minutes to update the status, please be patient...\n");
						connectButton.setEnabled(true);
					}
				});
				runner.start();
			}
		}
	}

	/*
	 * Create the GUI and show it. As with all GUI code, this must run
	 * on the event-dispatching thread.
	 */

	public mailRemoverGUI() {
		init();
		northPanel.add(hostLabel);
		northPanel.add(hostTextField);
		northPanel.add(usernameLabel);
		northPanel.add(userTextField);
		northPanel.add(passwordLabel);
		northPanel.add(userPasswordField);

		//Lay out the panel.
		SpringUtilities.makeCompactGrid(northPanel,
				3, 2, //rows, columns
				6, 6,        //initX, initY
				6, 6);       //xPad, yPad

		add(northPanel, BorderLayout.NORTH);
		add(scrollArea, BorderLayout.CENTER);
		add(connectButton, BorderLayout.SOUTH);

		setVisible(true);
		userTextField.requestFocus();
	}

	public void init() {
		mrGUI = this;

		northPanel = new JPanel(new SpringLayout());

		hostLabel = new JLabel("Host:");
		usernameLabel = new JLabel("Username:");
		passwordLabel = new JLabel("Password:");

		hostTextField = new JTextField("htctaomsg2.htc.com.tw");
		userTextField = new JTextField();
		userTextField.setSize(150, 20);

		userPasswordField = new JPasswordField();
		userPasswordField.setSize(150, 20);

		connectButton = new JButton("Connect");
		connectButton.addActionListener(new connectPressed());

		clientTextArea = new JTextArea();
		clientTextArea.setEditable(false);
		scrollArea = new JScrollPane(clientTextArea);
		scrollArea.setSize(230, 200);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(480, 640);
		setTitle("Mail Remover " + VERSION);
		setMinimumSize(new Dimension(480, 640));
		setLocationRelativeTo(null);
		getRootPane().setDefaultButton(connectButton);
	}
}
